/**
 * jeecg-boot-parent
 *
 * @author : tzy
 * @Date : 2020-12-21
 * @Description:
 **/

package com.hhd.pdf;

import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtils {

    static ThreadLocal<Date> start = new ThreadLocal<>();

    private static Object Class;

    public static boolean isMatch(String mapper, String formType) {

        if (mapper == null || formType == null || StringUtils.isEmpty(formType) || StringUtils.isEmpty(mapper))
            return false;

        Pattern pattern = Pattern.compile(mapper);
        Matcher matcher = pattern.matcher(formType);
        if (matcher.find()) return true;
        return false;
    }

//    public static void startTime() {
//        start.set(DateUtil.date(System.currentTimeMillis()));
//    }
//
//    public static void endTime(String title) {
//        Date end = DateUtil.date(System.currentTimeMillis());
//        System.out.println(title + "--" + DateUtil.between(start.get(), end, DateUnit.MS) + "毫秒");
//        start.remove();
//    }

    public static <T extends Annotation> T getAnnotationWithParent(Object object, Class<T> tClass) {
        T annotation = null;

        if (object instanceof Class) {
            try {
                Class aClass = (Class) object;
                while (Objects.isNull(annotation = (T) aClass.getAnnotation(tClass))) {
                    aClass = aClass.getSuperclass();
                    if (aClass == Object.class) return null;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return annotation;
    }

    public static boolean isEmpty(List list) {
        return list == null || list.size() == 0;
    }

    public static boolean isEmpty(String str) {
        return StringUtils.isEmpty(str);
    }

    public static boolean isEmpty(Map map) {
        return map == null || map.size() == 0;
    }

    public static boolean isEmpty(Set set) {
        return set == null || set.size() == 0;
    }

    public static boolean isEmpty(Object[] objects) {
        return objects == null || objects.length == 0;
    }

    public static boolean isEmpty(Object object) {
        return object == null;
    }

    public static boolean isContain(Object target, Object[] array) {
        for (Object o : array) {
            if (o.equals(target)) return true;
        }
        return false;
    }

    public static void log(Object... os) {
        for (int i = 0; i < os.length; i++) {
            Object o = os[i];
            System.out.print(o.toString());
            if (i < os.length - 1 && os.length > 1) {
                System.out.print(" ");
            }
        }
        System.out.println();
    }

    public static RuntimeException newException(Exception exception, String message) {
        RuntimeException e = new RuntimeException(message, exception.getCause());
        e.setStackTrace(exception.getStackTrace());

        return e;
    }

    public static String toLog(Object... object) {
        String res = "";
        if (isEmpty(object)) return res;
        StringBuilder stringBuilder = new StringBuilder();
        for (Object o : object) {
            stringBuilder.append(o.toString());
        }
        return stringBuilder.toString();
    }

    public static void isEmptyThrow(String str, RuntimeException exception) {
        if (isEmpty(str)) throw exception;
    }

    public static void isEmptyThrow(Object[] objs, RuntimeException exception) {
        if (isEmpty(objs)) throw exception;
    }

    public static void isEmptyThrow(Object obj, RuntimeException exception) {
        if (isEmpty(obj)) throw exception;
    }

    public static void isEmptyThrow(List obj, RuntimeException exception) {
        if (isEmpty(obj)) throw exception;
    }

    /**
     * 获取类的所有属性，包括父类
     *
     * @param object
     * @return
     */
    public static Field[] getAllFields(Object object) {
        if (object == null) return new Field[0];
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    /**
     * 获取类的所有属性，包括父类
     *
     * @param object
     * @return
     */
    public static Field[] getAllFields(Class object) {
        Class<?> clazz = object;
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    public static Set toSet(Object obj) {
        //集合类型
        if (obj instanceof Collection) {
            return toSetFromCollection((Collection) obj);
        }

        //字符串类型
        if (obj instanceof String) {
            return toSetFromString((String) obj);
        }

        //基本类型
        if (obj instanceof Integer || obj instanceof Short
                || obj instanceof Long || obj instanceof Character
                || obj instanceof Float || obj instanceof Double
                || obj instanceof Boolean) {
            HashSet set = new HashSet();
            set.add(obj);
            return set;
        }

        return null;
    }

    private static Set toSetFromString(String obj) {
        if (CommonUtils.isEmpty(obj)) return new HashSet();
        String[] split = obj.split(",");
        HashSet res = new HashSet();
        for (String s : split)
            res.add(s);

        return res;
    }

    private static Set<String> toSetFromCollection(Collection collection) {
        return new HashSet(collection);
    }

    public static Set<String> toStringSet(Object o) {
        Set set = toSet(o);
        if (CommonUtils.isEmpty(set)) return new HashSet<>();

        Set<String> res = new HashSet<>();
        for (Object o1 : set) {
            if (CommonUtils.isEmpty(o1)) continue;
            String[] split = o1.toString().split(",");
            for (String s : split) {
                if (CommonUtils.isEmpty(s)) continue;
                res.add(s.trim());
            }
        }

        return res;
    }

    public static String toCode(int i, int codeLength) {
        String res = i + "";
        while (res.length() < codeLength)
            res = "0" + res;
        return res;
    }

    public static <T> List<T> newList(T t) {
        LinkedList<T> res = new LinkedList<>();
        res.add(t);
        return res;
    }

    public static <T> List<T> newList(T... t) {
        if (isEmpty(t)) {
            return newList();
        }
        LinkedList<T> res = new LinkedList<>();
        for (T t1 : t) {
            res.add(t1);
        }
        return res;
    }

    public static <T> T copyTo(Object source, Class<T> t) {
        try {
            Object o = t.newInstance();
            BeanUtils.copyProperties(source, o);
            return (T) o;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> copyToList(Collection sources, Class<T> t) {
        if (isEmpty(sources)) return new LinkedList<>();
        try {
            List<T> objects = new LinkedList<>();
            for (Object source : sources) {
                objects.add(copyTo(source, t));
            }

            return objects;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static boolean isEqual(String a, String b) {
        if (isEmpty(a) && isEmpty(b)) return true;
        if (!isEmpty(a) && isEmpty(b)) return false;
        if (isEmpty(a) && !isEmpty(b)) return false;
        return a.equals(b);
    }

    public static boolean isEqual(Object a, Object b) {
        if (isEmpty(a) && isEmpty(b)) return true;
        if (!isEmpty(a) && isEmpty(b)) return false;
        if (isEmpty(a) && !isEmpty(b)) return false;
        return a.equals(b);
    }

    public static <T> Set<T> newSet(T... ts) {
        HashSet<T> set = new HashSet<>();
        if (isEmpty(ts)) return set;
        set.addAll(Arrays.asList(ts));
        return set;
    }

//    public static <K, V> Map<K, List<V>> group(Collection<V> collection, GroupHelper.KeyHolder<K, V> keyHolder) {
//        GroupHelper<K, V> kvGroupHelper = new GroupHelper<>(collection, keyHolder);
//        return kvGroupHelper.getGroup();
//    }

    public static <K, V> V mapGetOrDefault(Map<K, V> map, K key, DefaultValueGetter<V> defaultValueGetter) {
        if (map.containsKey(key)) return map.get(key);
        V value = defaultValueGetter.getValue();
        map.put(key, value);
        return value;
    }

    public static LinkedList newList() {
        return new LinkedList<>();
    }

    public static List distinct(Object... objs) {
        Set set = new LinkedHashSet();
        if (CommonUtils.isEmpty(objs)) return new LinkedList(set);

        for (Object obj : objs) {
            if (CommonUtils.isEmpty(obj)) continue;
            if (obj instanceof Collection) {
                Collection collection = (Collection) obj;
                set.addAll(collection);
            }
        }
        return new LinkedList(set);
    }

    public static interface DefaultValueGetter<V> {
        public V getValue();
    }
}
